<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原型与原型链</title>
</head>

<body>
    <script>
        /**
         * 显式原型与隐式原型

            1.每个函数都有一个prototype属性，它默认指向一个Object实例空对象（原型对象），原型对象中有一个属性constructor，它指向函数对象。

            2.每个函数function都有一个prototype，即显式原型（属性）；每个实例对象都有一个 _ _proto _ _，可称为隐式原型（属性）。

            3.实例对象的隐式原型的值为其构造函数的显式原型的值。
        */

        /**
         * 原型链

            1.访问一个对象的属性时，先在自身属性中查找， 如果找到就返回，如果没找到，沿着_ _ proto_ _这条链向上找，直到找到就返回，如果没找到，返回undefined
            2.别名：隐式原型链
            3.作用：查找对象属性（方法）
            4.Function的prototype与_ _ proto_ _是指向一个地方。
            5.所有函数的_ _ proto_ _都是相等的，因为都是New Function（）创建的，都等于Function.prototype。
            6.函数的显式原型指向的对象默认是空的Object实例对象（Object不满足）
            7.Object的原型对象是原型链尽头！（Object.prototype._ _ proto_ _=null）
            8.Function.prototype===Object.__proto__,Function.prototype===Function.__proto__,Function.__proto__===Object.__proto__ //true,true,true
            9.Object.__proto__.__proto__===Object.prototype // true
        */

        /**
        * 属性问题

           1.当我们为对象设置属性的时候，是不看原型链的，如果原型链中也有此属性，在读取该属性的时候，会读取属性内部的属性而不是原型对象的属性。
           2.读取对象属性的时候会自动到原型链中寻找
       */
        /**
          * instanceof
 
             1.A instanceof B：A是否是B这个构造函数的实例对象
                 A：实例对象
 
                 B：构造函数
                 如果函数B的显式原型在A对象的原型链上，返回true，否则返回false。
         */
        // function A(){
        //     // 构造函数

        // }
        // A.prototype.n = 1;
        // var b = new A();

        // //在原型中，= 一定要理解成 指向
        // A.prototype = {
        //     // A的原型对象，也是c的实例对象原型
        //     n: 2,
        //     m: 3
        // }
        // var c = new A();
        // console.log(b.n, b.m, c.n, c.m); //1，undefined，2,3
        function F() { }
        Object.prototype.a = function () {
            console.log('a()')
        }
        Function.prototype.b = function () {
            console.log('b()')
        }
        var f = new F()
        // console.log(Function.__proto__===Function.prototype) // true
        // console.log(Function.__proto__,Function.prototype,f)
        // console.log(Function.__proto__===Object.__proto__) // true
        // console.log(Function.__proto__===Object.prototype) // false 
        console.log(F.prototype,Object.__proto__,Object.prototype) // false
        console.log(Function.prototype===Object.__proto__,Function.prototype===Function.__proto__,Function.__proto__===Object.__proto__)// true,true,true
        console.log(Object.__proto__.__proto__===Object.prototype) // false
        // console.log(F.prototype,Object,Object.__proto__.constructor===Function,Object.__proto__===Function) // {constructor: ƒ}constructor: ƒ F()arguments: nullcaller: nulllength: 0name: "F"prototype: {constructor: ƒ}[[FunctionLocation]]: 原型与原型链.html:65[[Prototype]]: ƒ ()[[Scopes]]: Scopes[1][[Prototype]]: Object ƒ Object() { [native code] } true false
        // console.log(F.prototype.__proto__===Object.__proto__.__proto__) // true 
        f.a() 			// a()
        f.b() 			// error 
        F.a() 			// a() 
        F.b() 			// b() 此时的F作为实例对象 Function的构造函数是器本身 Function的prototype与_ _ proto_ _是指向一个地方。


    </script>

</body>

</html>